﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Collections;
using System.Reflection;
using System.Text.RegularExpressions;
using MySql.Data.MySqlClient;

namespace Daneas.Utility.Universals
{
    /// <summary>
    /// 用户类型转换
    /// </summary>
    public class Convers
    {
        #region MSSQLtype类型的转换

        /// <summary>
        ///  SqlDbType转换为C#数据类型
        /// </summary>
        /// <param name="sqlType"></param>
        /// <returns></returns>
        public static Type SqlType2CsharpType(SqlDbType sqlType)
        {
            switch (sqlType)
            {
                case SqlDbType.BigInt:
                    return typeof(Int64);
                case SqlDbType.Binary:
                    return typeof(Object);
                case SqlDbType.Bit:
                    return typeof(Boolean);
                case SqlDbType.Char:
                    return typeof(String);
                case SqlDbType.DateTime:
                    return typeof(DateTime);
                case SqlDbType.Decimal:
                    return typeof(Decimal);
                case SqlDbType.Float:
                    return typeof(Double);
                case SqlDbType.Image:
                    return typeof(Object);
                case SqlDbType.Int:
                    return typeof(Int32);
                case SqlDbType.Money:
                    return typeof(Decimal);
                case SqlDbType.NChar:
                    return typeof(String);
                case SqlDbType.NText:
                    return typeof(String);
                case SqlDbType.NVarChar:
                    return typeof(String);
                case SqlDbType.Real:
                    return typeof(Single);
                case SqlDbType.SmallDateTime:
                    return typeof(DateTime);
                case SqlDbType.SmallInt:
                    return typeof(Int16);
                case SqlDbType.SmallMoney:
                    return typeof(Decimal);
                case SqlDbType.Text:
                    return typeof(String);
                case SqlDbType.Timestamp:
                    return typeof(Object);
                case SqlDbType.TinyInt:
                    return typeof(Byte);
                case SqlDbType.Udt://自定义的数据类型
                    return typeof(Object);
                case SqlDbType.UniqueIdentifier:
                    return typeof(Object);
                case SqlDbType.VarBinary:
                    return typeof(Object);
                case SqlDbType.VarChar:
                    return typeof(String);
                case SqlDbType.Variant:
                    return typeof(Object);
                case SqlDbType.Xml:
                    return typeof(Object);
                default:
                    return null;
            }
        }

        /// <summary>
        /// string，double，long ，int 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static SqlDbType NetType2SqlType(Type type)
        {
            switch (type.ToString())
            {
                case "System.Int64":
                    return SqlDbType.BigInt;
                case "System.Decimal":
                    return SqlDbType.Decimal;
                case "System.Double":
                    return SqlDbType.Float;
                case "System.Int32":
                    return SqlDbType.Int;
                case "System.UInt32":
                    return SqlDbType.Int;
                case "System.Object":
                    return SqlDbType.Binary;
                case "System.Boolean":
                    return SqlDbType.Bit;
                case "System.String":
                    return SqlDbType.NVarChar;
                case "System.DateTime":
                    return SqlDbType.DateTime;
                case "System.Single":
                    return SqlDbType.Real;
                case "System.Byte":
                    return SqlDbType.TinyInt;
                default:
                    return SqlDbType.VarBinary;
            }

        }

        /// <summary>
        /// sql server数据类型（如：varchar）转换为SqlDbType类型
        /// </summary>
        /// <param name="sqlTypeString"></param>
        /// <returns></returns>
        public static SqlDbType SqlTypeString2SqlType(string sqlTypeString)
        {
            SqlDbType dbType = SqlDbType.Variant;//默认为Object

            switch (sqlTypeString)
            {
                case "int":
                    dbType = SqlDbType.Int;
                    break;
                case "varchar":
                    dbType = SqlDbType.VarChar;
                    break;
                case "bit":
                    dbType = SqlDbType.Bit;
                    break;
                case "datetime":
                    dbType = SqlDbType.DateTime;
                    break;
                case "decimal":
                    dbType = SqlDbType.Decimal;
                    break;
                case "float":
                    dbType = SqlDbType.Float;
                    break;
                case "image":
                    dbType = SqlDbType.Image;
                    break;
                case "money":
                    dbType = SqlDbType.Money;
                    break;
                case "ntext":
                    dbType = SqlDbType.NText;
                    break;
                case "nvarchar":
                    dbType = SqlDbType.NVarChar;
                    break;
                case "smalldatetime":
                    dbType = SqlDbType.SmallDateTime;
                    break;
                case "smallint":
                    dbType = SqlDbType.SmallInt;
                    break;
                case "text":
                    dbType = SqlDbType.Text;
                    break;
                case "bigint":
                    dbType = SqlDbType.BigInt;
                    break;
                case "binary":
                    dbType = SqlDbType.Binary;
                    break;
                case "char":
                    dbType = SqlDbType.Char;
                    break;
                case "nchar":
                    dbType = SqlDbType.NChar;
                    break;
                case "numeric":
                    dbType = SqlDbType.Decimal;
                    break;
                case "real":
                    dbType = SqlDbType.Real;
                    break;
                case "smallmoney":
                    dbType = SqlDbType.SmallMoney;
                    break;
                case "sql_variant":
                    dbType = SqlDbType.Variant;
                    break;
                case "timestamp":
                    dbType = SqlDbType.Timestamp;
                    break;
                case "tinyint":
                    dbType = SqlDbType.TinyInt;
                    break;
                case "uniqueidentifier":
                    dbType = SqlDbType.UniqueIdentifier;
                    break;
                case "varbinary":
                    dbType = SqlDbType.VarBinary;
                    break;
                case "xml":
                    dbType = SqlDbType.Xml;
                    break;
            }
            return dbType;
        }

        /// <summary>
        /// sqldbtype转成Type的string
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string GetTypeDefault(SqlDbType type)
        {
            switch (type)
            {
                case SqlDbType.BigInt:
                    return "Int64.MinValue";
                case SqlDbType.Binary:
                    return "null";
                case SqlDbType.Bit:
                    return "false";
                case SqlDbType.Char:
                    return "null";
                case SqlDbType.Decimal:
                    return "0";
                case SqlDbType.Float:
                    return "0";
                case SqlDbType.Image:
                    return "null";
                case SqlDbType.Int:
                    return "Int32.MinValue";
                case SqlDbType.Money:
                    return "0";
                case SqlDbType.NChar:
                    return "null";
                case SqlDbType.NText:
                    return "null";
                case SqlDbType.NVarChar:
                    return "null";
                case SqlDbType.Real:
                    return "0";
                case SqlDbType.SmallInt:
                    return "0";
                case SqlDbType.SmallMoney:
                    return "0";
                case SqlDbType.Text:
                    return "null";
                case SqlDbType.Timestamp:
                    return "null";
                case SqlDbType.TinyInt:
                    return "0";
                case SqlDbType.Udt://自定义的数据类型
                    return "null";
                case SqlDbType.UniqueIdentifier:
                    return "null";
                case SqlDbType.VarBinary:
                    return "null";
                case SqlDbType.VarChar:
                    return "null";
                case SqlDbType.Variant:
                    return "null";
                case SqlDbType.Xml:
                    return "null";
                case SqlDbType.DateTime:
                    return "DateTime.MinValue";
                case SqlDbType.SmallDateTime:
                    return "DateTime.MinValue";
                default:
                    return null;
            }
        }

        #endregion               

        /// <summary>
        /// datatable转成json
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string T2J(DataTable dt)
        {
            if (dt.Rows.Count == 0)
            {
                return "";
            }

            StringBuilder jsonBuilder = new StringBuilder();
            jsonBuilder.Append("{");

            jsonBuilder.Append(dt.TableName == "" ? "Table" : dt.TableName);
            jsonBuilder.Append(":[");//转换成多个model的形式 

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                jsonBuilder.Append("{");
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    jsonBuilder.Append("\"");
                    jsonBuilder.Append(dt.Columns[j].ColumnName);
                    jsonBuilder.Append("\":\"");
                    jsonBuilder.Append(dt.Rows[i][j].ToString());
                    jsonBuilder.Append("\",");
                }
                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
                jsonBuilder.Append("},");
            }

            jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            jsonBuilder.Append("]");
            jsonBuilder.Append("}");

            return jsonBuilder.ToString();
        }
    }

    /// <summary>
    /// 集合的转换
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Convers<T> where T : new()
    {
        /// <summary>
        /// list转datatable
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static DataTable L2T(IList list)
        {
            DataTable dt = new DataTable();

            if (list == null || list.Count <= 0)
            {
                return null;
            }
            //获取list成员的属性,构造datatable的columsname
            PropertyInfo[] propertys = list[0].GetType().GetProperties();

            foreach (PropertyInfo property in propertys)
            {
                dt.Columns.Add(property.Name, property.PropertyType);
            }

            //方法1
            for (int i = 0; i < list.Count; i++)
            {
                ArrayList array = new ArrayList();
                foreach (PropertyInfo property in propertys)
                {
                    object obj = property.GetValue(list[i], null);
                    array.Add(obj);
                }

                object[] arrayItems = array.ToArray();
                dt.LoadDataRow(arrayItems, true);
            }

            return dt;
        }

        /// <summary>
        /// datatab转list
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static List<T> T2L(DataTable dt)
        {
            if (dt == null || dt.Rows.Count <= 0)
            {
                return null;
            }

            // 定义集合    
            List<T> list = new List<T>();

            // 获得此模型的类型   
            Type type = typeof(T);
            string tempName = "";

            foreach (DataRow dr in dt.Rows)
            {
                T t = new T();
                // 获得此模型的公共属性      
                PropertyInfo[] propertys = t.GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    tempName = pi.Name;  // 检查DataTable是否包含此列    

                    if (dt.Columns.Contains(tempName))
                    {
                        // 判断此属性是否有Setter      
                        if (!pi.CanWrite) continue;

                        object value = dr[tempName];
                        if (value != DBNull.Value)
                            pi.SetValue(t, value, null);
                    }
                }
                list.Add(t);
            }
            return list;
        }

        /// <summary>
        /// List转json
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static string L2J(IList list)
        {
            DataTable dt = L2T(list);

            string json = "";

            if (dt == null || dt.Rows.Count <= 0)
            {
                return json;
            }

            json = Convers.T2J(dt);

            return json;
        }

        public static string Item2J(T t)
        {
            Type type = typeof(T);

            PropertyInfo[] pros = type.GetProperties();

            string back = "{";
            foreach (var item in pros)
            {
                string name = item.Name;
                PropertyInfo propertyInfo = type.GetProperty(name);

                object obj = propertyInfo.GetValue(t, null);

                Type temp = propertyInfo.GetType();

                if (temp == typeof(System.DateTime))
                {
                    back += "\"" + name + "\":\"" + (obj == null ? "2000-1-1" : Convert.ToDateTime(obj).ToString("yyyy-MM-dd HH:mm:ss")) + "\",";
                }

                if (temp == typeof(System.Int32))
                {
                    back += "\"" + name + "\":\"" + ((int)obj == Int32.MinValue ? "0" : obj.ToString()) + "\",";
                }

                if (temp == typeof(System.Int64))
                {
                    back += "\"" + name + "\":\"" + ((long)obj == Int64.MinValue ? "0" : obj.ToString()) + "\",";
                }

                if (temp == typeof(System.Double))
                {
                    back += "\"" + name + "\":\"" + ((double)obj == Double.MinValue ? "0" : obj.ToString()) + "\",";
                }


                if (temp == typeof(System.Decimal))
                {
                    back += "\"" + name + "\":\"" + ((decimal)obj == Decimal.MinValue ? "0" : obj.ToString()) + "\",";
                }


                if (temp == typeof(System.Boolean))
                {
                    back += "\"" + name + "\":\"" + (obj == null ? "false" : "true" + "\",");
                }

                else
                {
                    if (obj == null)
                    {
                        obj = "";
                    }

                    string tt = obj.ToString().Replace("\"", "'");

                    tt = Regex.Replace(tt, @"[\n\r]", "");

                    back += "\"" + name + "\":\"" + tt + "\",";
                }
            }
            back = back.TrimEnd(',');
            back += "}";
            return back;
        }
    }
}
